<template>
  <div id="cesiumContainer" ref="cesiumContainer"></div>
</template>

<script setup>
//引入cesium 引入样式 引入生命周期挂载
import * as Cesium from 'cesium';
import './Widgets/widgets.css';
import { onMounted } from 'vue';

//引入数据源
import planeData from '@/assets/plane.json';

//设置根目录静态资源 /代表根目录public
window.CESIUM_BASE_URL = '/';

onMounted(async () => {
  console.log('Cesium', Cesium);
  const viewer = new Cesium.Viewer('cesiumContainer', {
    // 是否显示信息窗口
    infoBox: false,
    //添加直接运行动画
    shouldAnimate: true,
    //添加默认地形
    terrainProvider: await Cesium.createWorldTerrainAsync({
      requestVertexNormals: true,
      requestWaterMask: true,
    }),
  });

  //添加3D建筑
  const osmBuildings = await Cesium.createOsmBuildingsAsync();
  viewer.scene.primitives.add(osmBuildings);

  //由于源数据没有时间点需要手动添加设置

  //1.设置采样点
  const positionProperty = new Cesium.SampledPositionProperty();

  //2.设置时间间隔 30s
  const timeStepInSeconds = 30;
  //3.设置整个飞行花费的时间
  const totalSeconds = (planeData.length - 1) * timeStepInSeconds;

  //4.设置起点何终点的时间
  const time = new Date('2022-03-09T23:10:00Z');
  //cesium默认使用的是儒略日的时间 需要进行转换
  //4.1设置转换后的起点时间
  const startJulianDate = Cesium.JulianDate.fromDate(time);
  // console.log('startJulianDate', startJulianDate); //JulianDate:{dayNumber: 2459648, secondsOfDay: 40237}
  //4.2设置终点时间 addSeconds将提供的秒数添加到提供的日期实例中。
  const stopJulianDate = Cesium.JulianDate.addSeconds(
    //参考的起点时间
    startJulianDate,
    //总共花费的时间
    totalSeconds,
    //返回新的时间
    new Cesium.JulianDate()
  );

  //5.将查看器的时间调整到起点和结束点的范围
  //5.1避免对起点和终点的设置时间进行修改影响到查看器的时间范围 这里使用时间克隆
  viewer.clock.startTime = startJulianDate.clone();
  viewer.clock.stopTime = stopJulianDate.clone();
  //5.2设置起始点为当前时间
  viewer.clock.currentTime = startJulianDate.clone();
  //5.3将进度条的时间线缩放到指定范围
  viewer.timeline.zoomTo(startJulianDate, stopJulianDate);

  //6.循环嵌入当前点的时间
  planeData.forEach((dataPoint, i) => {
    //当前点的时间
    const time = Cesium.JulianDate.addSeconds(
      startJulianDate,
      i * timeStepInSeconds,
      new Cesium.JulianDate()
    );
    //当前点的位置 转换经纬度为笛卡尔三维坐标
    const position = Cesium.Cartesian3.fromDegrees(
      dataPoint.longitude,
      dataPoint.longitude,
      dataPoint.height
    );

    //添加每个轨迹的采样点
    positionProperty.addSample(time, position);

    //添加点查看轨迹
    viewer.entities.add({
      position: position,
      point: {
        pixelSize: 10,
        color: Cesium.Color.RED,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 2,
      },
    });
  });

  //7.创建飞机
  const planeEnity = viewer.entities.add({
    //可用时间 TimeIntervalCollection时间间隔集合
    availability: new Cesium.TimeIntervalCollection([
      new Cesium.TimeInterval({
        start: startJulianDate,
        stop: stopJulianDate,
      }),
    ]),
    name: '飞机',
    //设置可用的时间
    position: positionProperty,
    //模型朝向 VelocityOrientationProperty会自动根据采样点,计算出飞机的速度和方向
    orientation: new Cesium.VelocityOrientationProperty(positionProperty),
    model: {
      uri: './model/Air.glb',
      minimumPixelSize: 128,
      maximumScale: 20000,
    },
    //绘制轨迹线 路径图像函数
    path: new Cesium.PathGraphics({
      width: 5,
    }),
  });

  //8.设置相机追踪运动物体
  viewer.trackedEntity = planeEnity;

  //9.加快时间速率 1s等于10s
  viewer.clock.multiplier = 100;
});
</script>

<style>
/* 初始化边距 */
* {
  margin: 0;
  padding: 0;
}
/* 初始化模型和屏幕占位 */
#cesiumContainer {
  width: 100vw;
  height: 100vh;
}
</style>
